package com.hksj.sglm.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hksj.cbm.entity.DeviceInstance;
import com.hksj.cbm.entity.SpaceModel;
import com.hksj.cbm.entity.SpecialityModel;
import com.hksj.cbm.service.SpaceModelService;
import com.hksj.cbm.service.SpecialityModelService;
import com.hksj.common.core.common.Constants;
import com.hksj.common.core.common.SpecialityModelCodeEnum;
import com.hksj.common.core.util.DateUtil;
import com.hksj.sglm.dto.SpecialGasCockpitDTO;
import com.hksj.sglm.mapper.SpecialGasCockpitLeftMapper;
import com.hksj.sglm.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author fjt
 * @data 2024/9/12 18:22
 * @describe 特气泄漏驾驶舱左侧
 */
@Slf4j
@Service
public class SpecialGasCockpitLeftService {

    @Autowired
    private SpaceModelService spaceModelService;
    @Autowired
    private SpecialityModelService specialityModelService;
    @Autowired
    private SpecialGasCockpitLeftMapper specialGasCockpitLeftMapper;


    /**
     * 设备概览
     * @param dto
     * @return
     */
    public List<SpecialGasDeviceOverviewVO> deviceOverView(SpecialGasCockpitDTO dto){
        List<SpecialGasDeviceOverviewVO> list = new ArrayList<>(2);
        list.add(deviceOverViewByType(dto, SpecialityModelCodeEnum.Teqxl_product.getCode()));
        list.add(deviceOverViewByType(dto, SpecialityModelCodeEnum.Qityl_product.getCode()));
        return list;
    }

    /**
     * 查询指定产品类型的概览
     * @param productCategoryKey 产品类型代码(模糊查询，以特定字符开头)
     * @return
     */
    private SpecialGasDeviceOverviewVO deviceOverViewByType(SpecialGasCockpitDTO dto, String productCategoryKey){
        dto.setCode(SpecialityModelCodeEnum.special_gas_leakage.getCode());
        dto.setProductCategoryKey(productCategoryKey);
        List<DeviceInstance> deviceList = specialGasCockpitLeftMapper.deviceOverView(dto);
        SpecialGasDeviceOverviewVO overviewVO = new SpecialGasDeviceOverviewVO();
        if (CollUtil.isEmpty(deviceList)){
            return overviewVO;
        }
        // 在线
        List<DeviceInstance> onLineDeviceList = deviceList.stream()
                .filter(device -> "online".equals(device.getState()))
                .collect(Collectors.toList());
        // 离线
        List<DeviceInstance> offLineDeviceList = deviceList.stream()
                .filter(device -> "offline".equals(device.getState()))
                .collect(Collectors.toList());

        // 未激活
        List<DeviceInstance> notActiveList = deviceList.stream()
                .filter(device -> "notActive".equals(device.getState()))
                .collect(Collectors.toList());

        overviewVO.setTotal(deviceList.size());
        overviewVO.setDeviceCode(productCategoryKey);
        overviewVO.setOnlineNum(CollUtil.isNotEmpty(onLineDeviceList) ? onLineDeviceList.size() : 0);
        overviewVO.setOfflineNum(CollUtil.isNotEmpty(offLineDeviceList) ? offLineDeviceList.size() : 0);
        overviewVO.setNotActiveNum(CollUtil.isNotEmpty(notActiveList) ? notActiveList.size() : 0);
        return overviewVO;
    }


    /**
     * 统计设备当前报警数量
     * @param dto
     * @return
     */
    public SpecialGasInAlarmNumVO currentAlarmNum(SpecialGasCockpitDTO dto){
        dto.setCode(SpecialityModelCodeEnum.special_gas_leakage.getCode());
        List<SpecialGasAlarmDeviceListVO> list = specialGasCockpitLeftMapper.queryCurrentAlarmNumGroupByProductCategoryKey(dto);
        if (CollUtil.isEmpty(list)){
            return null;
        }

        List<SpecialGasInAlarmNumVO.SpecialGasAlarmKindNumVO> voList = new ArrayList<>(2);
        // 特气泄漏监测传感器
        List<SpecialGasAlarmDeviceListVO> leakDeviceList = list.stream()
                .filter(device -> SpecialityModelCodeEnum.Teqxl_product.getCode().equals(device.getProductCategoryKey()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(leakDeviceList)){
            SpecialGasInAlarmNumVO.SpecialGasAlarmKindNumVO vo = SpecialGasInAlarmNumVO.SpecialGasAlarmKindNumVO.builder()
                    .deviceCode(SpecialityModelCodeEnum.Teqxl_product.getCode()).num(leakDeviceList.size()).build();
            voList.add(vo);
        }

        // 气体压力传感器
        List<SpecialGasAlarmDeviceListVO> pressureList = list.stream()
                .filter(device -> device.getProductCategoryKey().startsWith(SpecialityModelCodeEnum.Qityl_product.getCode()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(pressureList)){
            SpecialGasInAlarmNumVO.SpecialGasAlarmKindNumVO vo = SpecialGasInAlarmNumVO.SpecialGasAlarmKindNumVO.builder()
                    .deviceCode(SpecialityModelCodeEnum.Qityl_product.getCode()).num(pressureList.size()).build();
            voList.add(vo);
        }

        SpecialGasInAlarmNumVO vo = new SpecialGasInAlarmNumVO();
        vo.setTotal(voList.stream().mapToInt(SpecialGasInAlarmNumVO.SpecialGasAlarmKindNumVO::getNum).sum());
        vo.setList(voList);
        return vo;
    }


    /**
     * 报警数量排名
     * @param dto
     * @return
     */
    public List<SpecialGasAlarmNumGroupRankingVO> alarmNumRanking(SpecialGasCockpitDTO dto){
        // 按设备分组统计报警次数
        dto.setStartTime(DateUtil.convertToDate(DateUtil.convertToLocalDate(DateUtil.getNow()).minusDays(6)));
        dto.setEndTime(DateUtil.getYmdHms(DateUtil.getFormatDate(DateUtil.getNow(), DateUtil.DEFAULT_FORMAT_DATE) + " 23:59:59"));
        dto.setCode(SpecialityModelCodeEnum.special_gas_leakage.getCode());
        List<SpecialGasAlarmNumRankingVO> rankingVoList = specialGasCockpitLeftMapper.alarmNumRankingGroupDevice(dto);
        if (CollUtil.isEmpty(rankingVoList)){
            return null;
        }

        // 查询设置的统计方式(按楼层/科室)
        LambdaQueryWrapper<SpecialityModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SpecialityModel::getCode, SpecialityModelCodeEnum.special_gas_leakage.getCode());
        SpecialityModel specialityModel = specialityModelService.getOne(queryWrapper);
        if (ObjectUtil.isNull(specialityModel)){
            throw new RuntimeException("无线漏水监测系统缺少专业模型配置信息");
        }

        if (StringUtils.isNotBlank(dto.getPaths())){
            SpaceModel spaceModel = spaceModelService.querySpaceModelByPaths(dto.getPaths());
            Assert.notNull(spaceModel, "空间模型表中不存在此路径");
            // 是楼栋，则按科室或楼层排名
            if (Constants.FOUR_STR.equals(spaceModel.getSpaceItemValue())) {
                return groupByBuilding(rankingVoList, specialityModel);
            }else {
                // 非楼栋，则按单个设备排名  按报警次数降序排序
                List<SpecialGasAlarmNumGroupRankingVO> voList = new ArrayList<>(rankingVoList.size());
                rankingVoList.forEach(rankingVo -> {
                    SpecialGasAlarmNumGroupRankingVO vo = SpecialGasAlarmNumGroupRankingVO.builder()
                            .pathName(rankingVo.getDeviceName()).num(rankingVo.getNum()).build();
                    voList.add(vo);
                });

                // 按报警次数降序排序
                return voList.stream()
                        .sorted(Comparator.comparing(SpecialGasAlarmNumGroupRankingVO::getNum, Comparator.reverseOrder()))
                        .collect(Collectors.toList());
            }
        }else {
            // 路径为空时默认按楼层或科室分组统计
            return groupByBuilding(rankingVoList, specialityModel);
        }
    }


    private List<SpecialGasAlarmNumGroupRankingVO> groupByBuilding(List<SpecialGasAlarmNumRankingVO> rankingVoList, SpecialityModel specialityModel){
        // 统计方式(1=按楼层统计 2=按科室统计)
        Integer statisticalMethod = specialityModel.getStatisticalMethod();
        if (Constants.ONE.equals(statisticalMethod)){
            // 楼层
            Map<String, List<SpecialGasAlarmNumRankingVO>> rankingMap = rankingVoList.stream()
                    .collect(Collectors.groupingBy(r -> r.getFloorId() + "-" + r.getFloorName()));
            return convertToSpecialGasAlarmNumGroupRankingVO(rankingMap);
        }
        if (Constants.TWO.equals(statisticalMethod)){
            // 科室
            Map<String, List<SpecialGasAlarmNumRankingVO>> rankingMap = rankingVoList.stream()
                    .collect(Collectors.groupingBy(r -> r.getDepartmentItemValue() + "-" + r.getDepartmentItemValueName()));
            return convertToSpecialGasAlarmNumGroupRankingVO(rankingMap);
        }
        return null;
    }


    private List<SpecialGasAlarmNumGroupRankingVO> convertToSpecialGasAlarmNumGroupRankingVO(Map<String, List<SpecialGasAlarmNumRankingVO>> rankingMap){
        if (CollUtil.isEmpty(rankingMap)){
            return null;
        }
        List<SpecialGasAlarmNumGroupRankingVO> rankingVOList = new ArrayList<>(rankingMap.size());

        for(Map.Entry<String, List<SpecialGasAlarmNumRankingVO>> entry : rankingMap.entrySet()){
            String pathName = entry.getKey().split("-")[1];
            Integer num = entry.getValue().stream().mapToInt(SpecialGasAlarmNumRankingVO::getNum).sum();
            SpecialGasAlarmNumGroupRankingVO rankingVO = SpecialGasAlarmNumGroupRankingVO.builder().pathName(pathName).num(num).build();
            rankingVOList.add(rankingVO);
        }

        // 按报警次数降序排序
        return rankingVOList.stream()
                .sorted(Comparator.comparing(SpecialGasAlarmNumGroupRankingVO::getNum, Comparator.reverseOrder()))
                .collect(Collectors.toList());
    }


}
